<script lang="ts" setup>
import SearchPlace from '@/components/map/SearchPlace.vue'
import { reactive, ref, shallowRef, onMounted, computed } from 'vue'
import { useMap } from '@/hooks/useMap'
import CenterImg from '@/assets/map/bikeTermAMap/center.png'
import MapMarkerImg from '@/assets/map/bikeTermAMap/mapMarker.png'
import LeftImg from '@/assets/map/bikeTermAMap/left.png'
import RightImg from '@/assets/map/bikeTermAMap/right.png'
import { RentTimeType, DepositType, VoltageType } from '@/types/enum'
import { queryProductByMap } from '@/api/term'
import { queryProductByMapResponseData, queryProductByMapTableCol } from '@/api/term/types/term'
import { getToken } from '@/utils/cache/cookies'
import { useDebounceFn } from '@vueuse/core'
import { formatMeter } from '@/utils'
import { useRouter } from 'vue-router'
import { useMapPoint } from '@/store/modules/mapPoint'
defineOptions({
  name: 'BikeTermAMap'
})
const dialogVisible = ref<boolean>(false)
const center = reactive({
  longtitude: 121.39175618590401,
  latitude: 31.233051923893633
})
const isInit = ref<boolean>(false)
const mapContainer = ref<HTMLDivElement>()
const { map, auto, initAmap, placeSearch } = useMap(mapContainer, [
  center.longtitude,
  center.latitude
])
/**
 * 数据声明
 */
interface Form {
  depositType: '' | DepositType
  voltage: '' | VoltageType
  rentTime: '' | RentTimeType
}
const form = reactive<Form>({
  depositType: '',
  voltage: '',
  rentTime: ''
})
const termData = ref<queryProductByMapResponseData>([])
const markerList = shallowRef<AMap.LngLat[]>([])
const pointList = shallowRef<AMap.Marker[]>([])
const rightMarker = shallowRef<AMap.Marker>()
/**
 * 计算圆中心点右边得点经纬度
 */
const getRightCenter = (longtitude: number, latitude: number, radius: number) => {
  const perimeter = 2 * Math.PI * 6371000
  const perimeter_latitude = perimeter * Math.cos((Math.PI * latitude) / 180)
  const longtitude_per_mi = 360 / perimeter_latitude
  const rightLo = longtitude + radius * longtitude_per_mi
  const right = new AMap.LngLat(rightLo, latitude)
  return right
}
/**
 * 格式化金额
 */
const moneyFormats = (money: number) => {
  return money.toLocaleString('zh', { style: 'currency', currency: 'CNY' })
}
/** 地图初始化 */
const init = async () => {
  isInit.value = await initAmap()
  handleCoverInit()
  getData()
  addMapEvent()
}
/**
 * 中心点
 */
const centerMarker = shallowRef<AMap.Marker>()
/**
 * 中心圆形覆盖物
 */
const centerCircle = shallowRef<AMap.Circle>()
const circleRadius = ref<number>(1000)
/**
 * 过滤器 文本格式化半径
 */
const radiusTitle = computed(() => circleRadius.value / 1000 + '公里')
/**
 * 初始化覆盖物
 */
const handleCoverInit = () => {
  const centerLngLat = new AMap.LngLat(center.longtitude, center.latitude)
  centerMarker.value = new AMap.Marker({
    map: map.value!,
    position: centerLngLat,
    icon: new AMap.Icon({
      size: new AMap.Size(47, 50),
      imageSize: new AMap.Size(47, 50),
      image: CenterImg
    }),
    anchor: 'bottom-center',
    offset: new AMap.Pixel(0, 0),
    draggable: true,
    cursor: 'pointer',
    clickable: true
  })
  //监听中心点移动事件 移动覆盖范围中心
  centerMarker.value.on('dragend', moveCenter)
  centerCircle.value = new AMap.Circle({
    center: centerLngLat,
    radius: circleRadius.value,
    fillColor: '#3677EC',
    fillOpacity: 0.18,
    strokeOpacity: 0
  })
  map.value?.add(centerCircle.value)
  const right = getRightCenter(center.longtitude, center.latitude, circleRadius.value)
  rightMarker.value = new AMap.Marker({
    map: map.value!,
    position: right,
    anchor: 'bottom-center',
    offset: new AMap.Pixel(0, 0),
    label: {
      content: radiusTitle.value,
      direction: 'right'
    },
    content: createAdjustRadiusContent()
  })
}
/**
 * 为地图添加事件
 */
const addMapEvent = () => {
  const mapContainer = document.getElementById('map-container')
  mapContainer?.addEventListener('click', handleAdjustButtonClick)
}
/**
 * 处理调整按钮事件
 */
const handleAdjustButtonClick = (event: any) => {
  // 检查是否点击了 "减少半径" 按钮
  if (event.target.className.includes('slow-radius')) {
    slowRadius()
  }
  // 检查是否点击了 "增加半径" 按钮
  if (event.target.className.includes('add-radius')) {
    addRadius()
  }
}
/**
 * 处理移动圆中心事件
 */
const moveCenter = useDebounceFn((e) => {
  const lnglat: AMap.LngLat = e.lnglat
  center.longtitude = lnglat.getLng()
  center.latitude = lnglat.getLat()
  centerCircle.value?.setCenter(lnglat)
  map.value?.setCenter(lnglat)
  const right = getRightCenter(lnglat.getLng(), lnglat.getLat(), circleRadius.value)
  rightMarker.value?.setPosition(right)
  getData()
}, 1000)
/**
 * 增加圆半径
 */
const addRadius = () => {
  circleRadius.value += 1000
  centerCircle.value?.setRadius(circleRadius.value)
  rightMarker.value?.setLabel({
    content: radiusTitle.value,
    direction: 'right'
  })
  const right = getRightCenter(center.longtitude, center.latitude, circleRadius.value)
  rightMarker.value?.setPosition(right)
  getData()
}
/**
 * 减少圆半径
 */
const slowRadius = () => {
  if (circleRadius.value == 1000) {
    return
  }
  circleRadius.value -= 1000
  centerCircle.value?.setRadius(circleRadius.value)
  rightMarker.value?.setLabel({
    content: radiusTitle.value,
    direction: 'right'
  })
  const right = getRightCenter(center.longtitude, center.latitude, circleRadius.value)
  rightMarker.value?.setPosition(right)
  getData()
}
/**
 * 创建调整半径内容dom
 */
const createAdjustRadiusContent = () => {
  return `
  <div class="adjust-button">
                <img class="slow-radius"  src="${LeftImg}"/>
                <img class="add-radius" src="${RightImg}"/>
              </div>
  `
}
/**
 * 获取数据长租套餐数据
 */
const getData = () => {
  queryProductByMap({
    longtitude: center.longtitude,
    latitude: center.latitude,
    token: getToken() ?? '',
    voltage: form.voltage,
    depositType: form.depositType,
    rentTime: form.rentTime,
    range: circleRadius.value / 1000
  }).then((res) => {
    if (res.statusCode === '0') {
      termData.value = filterData(res.data as queryProductByMapResponseData)
      termData.value = handleMapData(termData.value)
      markerList.value = handleMarKerList(termData.value)
      createMarker(markerList.value)
      dialogVisible.value = true
    } else {
      termData.value = []
      markerList.value = []
      map.value?.remove(pointList.value)
      pointList.value = []
    }
  })
}
/**
 * 去除storeInfo中经纬度为0 或null等情况
 */
const filterData = (data: queryProductByMapResponseData) => {
  return data.filter((term) => term.storeInfo.longtitude && term.storeInfo.latitude)
}
/**
 * 处理接口返回数据
 */
const handleMapData = (data: queryProductByMapResponseData) => {
  return data.map((term) => {
    return {
      ...term,
      distance: AMap.GeometryUtil.distance(
        new AMap.LngLat(Number(term.storeInfo.longtitude), Number(term.storeInfo.latitude)),
        [center.longtitude, center.latitude]
      )
    }
  })
}
/**
 * 处理搜索到的门店点
 */
const handleMarKerList = (data: queryProductByMapResponseData) => {
  return data.map(
    (term) => new AMap.LngLat(Number(term.storeInfo.longtitude), Number(term.storeInfo.latitude))
  )
}
/**
 * 生成门店点覆盖物
 */
const createMarker = (data: AMap.LngLat[]) => {
  data.forEach((marker, index) => {
    const point = new AMap.Marker({
      position: marker,
      map: map.value!,
      icon: new AMap.Icon({
        size: new AMap.Size(43, 54),
        image: MapMarkerImg,
        imageOffset:
          index < 10
            ? new AMap.Pixel(0 - 43 * index, 0)
            : new AMap.Pixel(0 - 43 * (index - 10), -54),
        imageSize: new AMap.Size(430, 108)
      })
    })
    pointList.value.push(point)
  })
}
/**
 * 处理可租周期
 */
const handleRentTime = (command: RentTimeType) => {
  form.rentTime = command
  getData()
}
/**
 * 处理押金类型
 */
const handleDepositType = (command: DepositType) => {
  form.depositType = command
  getData()
}
/**
 * 处理额定电压
 */
const handleVoltage = (command: VoltageType) => {
  form.voltage = command
  getData()
}
/**
 * 搜索组件 搜索后与当前页面联动
 */
const handleSearchPlace = (lnglat: AMap.LngLat) => {
  center.longtitude = lnglat.getLng()
  center.latitude = lnglat.getLat()
  centerMarker.value?.setPosition(lnglat)
  centerCircle.value?.setCenter(lnglat)
  map.value?.setCenter(lnglat)
  const right = getRightCenter(lnglat.getLng(), lnglat.getLat(), circleRadius.value)
  rightMarker.value?.setPosition(right)
  getData()
}
/** 查看取还车地点 */
const router = useRouter()
const { setType, setText, setReturnAddress, setBindAddress } = useMapPoint()
const showPoint = (term: queryProductByMapTableCol) => {
  setType('return')
  setText('查看取车点')
  setReturnAddress(term.returnAddress)
  setBindAddress(term.bindAddress)
  router.push({
    name: 'ShowPointAMap',
    query: {
      name: term.name
    }
  })
}
onMounted(() => {
  init()
})
</script>

<template>
  <div class="xy-map-container">
    <div ref="mapContainer" id="map-container">
      <search-place
        :auto="auto"
        :map="map!"
        :place-search="placeSearch"
        :is-link-age="true"
        @select="handleSearchPlace"
      />
      <div class="search_result_dialog" v-if="dialogVisible">
        <div class="search_result_title">
          <el-dropdown @command="handleDepositType">
            <span>
              <span> 免押类型 </span
              ><el-icon class="el-icon--right">
                <arrow-down />
              </el-icon>
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="">不限</el-dropdown-item>
                <el-dropdown-item command="AlipayCredit">芝麻信用分</el-dropdown-item>
                <el-dropdown-item command="WeChatCredit">微信支付分</el-dropdown-item>
                <el-dropdown-item command="Deposit">不支持免押</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-dropdown @command="handleVoltage">
            <span>
              电池电压<el-icon class="el-icon--right"> <arrow-down /> </el-icon
            ></span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="">不限</el-dropdown-item>
                <el-dropdown-item command="48V">48V</el-dropdown-item>
                <el-dropdown-item command="60V">60V</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-dropdown @command="handleRentTime">
            <span>
              可租周期<el-icon class="el-icon--right"> <arrow-down /> </el-icon
            ></span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="">不限</el-dropdown-item>
                <el-dropdown-item command="1d">日租</el-dropdown-item>
                <el-dropdown-item command="7d">周租</el-dropdown-item>
                <el-dropdown-item command="30d">月租</el-dropdown-item>
                <el-dropdown-item command="90d">季租</el-dropdown-item>
                <el-dropdown-item command="360d">年租</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
        <div class="el-dialog__body">
          <el-scrollbar>
            <div class="search_result_body">
              <div v-for="(term, index) in termData" :key="index" class="search_result_item">
                <div class="item_info">
                  <div class="list" :class="'list-' + (index + 1)" />
                  <div flex flex-col>
                    <div class="info-1" flex justify-between items-center>
                      <span>{{ term.storeInfo.storeName }}</span>
                      <span v-if="term.distance">{{ formatMeter(term.distance) }}</span>
                    </div>
                    <div class="info-2">
                      <div>
                        <span>{{ term.name }}</span>
                        <div>
                          <span>型号:{{ term.productModel }}</span>
                          <span>电压:{{ term.inputVoltage }}</span>
                        </div>
                        <div>
                          <el-tag
                            type="warning"
                            plain
                            v-for="(item, index) in term.tags.split('|')"
                            :key="index"
                            >{{ item }}</el-tag
                          >
                        </div>
                      </div>
                      <img :src="term.imageUrls.split(',')[0]" alt="" />
                    </div>
                    <div class="info-3" flex flex-col>
                      <div flex flex-row>
                        <div>
                          <span>押金配置:</span>
                        </div>
                        <ul>
                          <li v-for="(type, i) in term.supportDepositTypes" :key="i">
                            <span v-if="type.depositType !== 'Deposit'"
                              >{{ type.depositDescription }}免押</span
                            >
                            <span v-else>押金{{ type.deposit }}元</span>
                          </li>
                        </ul>
                      </div>
                      <div flex flex-col>
                        <div>
                          <span class="info-3_rent">{{ moneyFormats(term.rent ?? 0) }}</span>
                          <span class="info-3_origin">{{
                            moneyFormats(term.originRent ?? 0)
                          }}</span>
                          <span class="info-3_depositType">{{ term.shortName }}</span>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
                <el-button plain @click="showPoint(term)">查看取/还车地点 ></el-button>
              </div>
            </div>
          </el-scrollbar>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
$markerWidth: 43;
$markerHeight: 54;
$listIconWidth: 28;
$listIconWidth: 32;
$length: 20;
:deep(.search_result_dialog) {
  position: absolute;
  right: 20px;
  top: 20px;
  max-height: calc(100% - 80px);
  height: 100%;
  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.1);
  border-radius: 10px;
  z-index: 999;
  width: 340px;
  background: #fff;
  .search_result_title {
    display: flex;
    flex-direction: row;
    background: #fff;
    border: 1px solid #eeeeee;
    padding: 10px;
    box-sizing: border-box;
    > .el-dropdown {
      width: calc(100% / 3);
      align-items: center;
      justify-content: center;
      border-radius: 5px;
      border: 1px solid #eeeeee;
      > span {
        line-height: 33px;
        cursor: pointer;
      }
      &:hover {
        background: #f5f5f5;
        span {
          color: #ff6d75;
        }
        .el-icon--right {
          transform: rotate(180deg);
        }
      }
      &:first-child {
        border-right: 0px;
      }
      &:last-child {
        border-left: 0px;
      }
    }
  }
  .el-dialog__body {
    padding: 10px;
    box-sizing: border-box;
    overflow: auto;
    box-sizing: border-box;
    width: 100%;
    height: calc(100% - 75px);
    background: #f7f8fa;
    div.search_result_body {
      display: flex;
      flex-direction: column;
      width: 100%;
      .search_result_item {
        display: flex;
        flex-direction: column;
        background: #ffffff;
        margin-bottom: 10px;
        box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.06);
        border-radius: 5px;
        width: 100%;
        .item_info {
          display: flex;
          flex-direction: row;
          margin-top: 5px;
          width: 100%;
          .list {
            width: 28px;
            height: 32px;
            background-image: url(@/assets/map/bikeTermAMap/listIcon.png);
            background-repeat: no-repeat;
          }
          @for $i from 1 through $length {
            .list-#{$i} {
              @if ($i < 11) {
                background-position: calc(0px - (28px * (#{$i} - 1))) 0;
              } @else {
                background-position: calc(0px - 28px * ((#{$i} - 11))) -32px;
              }
            }
          }
          > div:last-child {
            box-sizing: border-box;
            width: calc(100% - 32px);
            .info-1 {
              line-height: 17px;
              font-size: 12px;
              font-family: PingFang SC;
              color: #333333;
              margin-bottom: 8px;
              > span:last-child {
                color: #999999;
              }
            }
            .info-2 {
              display: flex;
              align-items: center;
              justify-content: space-between;
              > div {
                > *:first-child {
                  font-size: 14px;
                  font-family: PingFang SC;
                  line-height: 20px;
                  color: #ff6d75;
                  margin-bottom: 2px;
                }
                > *:nth-child(2) {
                  font-size: 12px;
                  font-family: PingFang SC;
                  line-height: 17px;
                  color: #666666;
                  margin-bottom: 4px;
                  > span:last-child {
                    margin-left: 10px;
                  }
                }
                > *:last-child {
                  .el-tag {
                    margin-left: 5px;
                  }
                  .el-tag:first-child {
                    margin-left: 0px;
                  }
                }
              }
              img {
                width: 56px;
                height: 56px;
              }
            }
            .info-3 {
              background: #f7f8fa;
              margin: 5px;
              border-radius: 5px;
              > div:first-child {
                background: #fff;
                border-radius: 2px;
                margin: 5px;
                padding: 5px;
                > div:first-child {
                  white-space: nowrap;
                }
                ul {
                  counter-reset: section;
                  list-style: none;
                  display: inline-block;
                  padding: 0px;
                  margin: 0 0 0 5px;
                }

                li {
                  margin: 0 10px 0px 0;
                  display: flex;
                  align-items: center;
                }

                li:before {
                  content: counter(section);
                  counter-increment: section;
                  display: inline-block;
                  width: 14px;
                  height: 14px;
                  margin: 0 5px 0 0;
                  border: 1px solid #ccc;
                  border-radius: 100%;
                  text-align: center;
                  transform: scale(0.8);
                }
                span {
                  color: #666666;
                  font-size: 12px;
                  font-family: PingFang SC;
                  line-height: 12px;
                }
              }
              > div:last-child {
                display: flex;
                margin-left: 5px;
                > div {
                  margin-bottom: 5px;
                }
                .info-3_rent {
                  font-size: 12px;
                  font-family: PingFang SC;
                  line-height: 17px;
                  color: #f3860a;
                }
                .info-3_origin {
                  font-size: 12px;
                  display: inline-block;
                  transform: scale(0.8);
                  font-family: PingFang SC;
                  line-height: 14px;
                  color: #999999;
                  text-decoration: line-through;
                  margin-left: 5px;
                  margin-right: 10px;
                }
                .info-3_depositType {
                  font-size: 12px;
                  font-family: PingFang SC;
                  line-height: 17px;
                  color: #333333;
                }
              }
            }
          }
        }
        > div:last-child {
          .el-button {
            width: 100%;
            border: none;
          }
        }
        &:last-child {
          margin-bottom: 0px;
        }
      }
    }
  }
}
:deep(.adjust-button) {
  width: 30px;
  height: 18px;
  background: #ffffff;
  border: 1px solid #938e99;
  border-radius: 10px;
  z-index: 999;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  > img {
    width: 6px;
    height: 8px;
    cursor: pointer;
  }
  > img:last-child {
    margin-left: 6px;
  }
}
</style>
